/********************************************
 * 功能说明: Web端Lessee基础业务控制器
 * 模块名称:
 * 系统名称:
 * 软件版权: Frank
 * 系统版本: 1.0.0.1
 * 开发人员:
 * 开发时间: 2020-03-24 10:09:23
 * 审核人员:
 * 相关文档:
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.spring.arch.operation.tenant.web.controller;

import com.codahale.metrics.annotation.Timed;
import com.querydsl.core.types.Predicate;
import com.spring.arch.common.constants.IConstants;
import com.spring.arch.common.dto.result.PageResultDTO;
import com.spring.arch.common.dto.result.ResultDTO;
import com.spring.arch.common.exception.ExceptionHolder;
import com.spring.arch.operation.tenant.repository.LesseeRepository;
import com.spring.arch.operation.tenant.web.converter.WebLesseeContactConverter;
import com.spring.arch.operation.tenant.web.converter.WebLesseeInvoiceConverter;
import com.spring.arch.common.constants.IConstants;
import com.spring.arch.common.dto.result.PageResultDTO;
import com.spring.arch.common.dto.result.ResultDTO;
import com.spring.arch.common.exception.ExceptionHolder;
import com.spring.arch.operation.tenant.errorcode.TenantErrorCode;
import com.spring.arch.operation.tenant.model.Lessee;
import com.spring.arch.operation.tenant.model.LesseeContact;
import com.spring.arch.operation.tenant.model.LesseeInvoice;
import com.spring.arch.operation.tenant.repository.LesseeRepository;
import com.spring.arch.operation.tenant.service.LesseeService;
import com.spring.arch.operation.tenant.web.converter.WebLesseeContactConverter;
import com.spring.arch.operation.tenant.web.converter.WebLesseeConverter;
import com.spring.arch.operation.tenant.web.converter.WebLesseeInvoiceConverter;
import com.spring.arch.operation.tenant.web.dto.WebLesseeDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.querydsl.binding.QuerydslPredicate;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.UUID;


/**
 * Web端Lessee基础业务控制器
 * @author
 * @version 1.0.0.1
 * @since 2020-03-24 10:09:23
 */
@Slf4j
@RestController
@RequestMapping(value = "/operation/w/lessee", produces = MediaType.APPLICATION_JSON_VALUE)
@Api(tags = {"Web端租客管理" })
public class WebLesseeController {

    @Autowired
    private LesseeService lesseeService;
    @Autowired
    private LesseeRepository lesseeRepository;
    @Autowired
    private WebLesseeConverter lesseeConverter;
    @Autowired
    private WebLesseeContactConverter lesseeContactConverter;
    @Autowired
    private WebLesseeInvoiceConverter lesseeInvoiceConverter;


    /**
     * 新建操作
     *
     * @param lesseeDTO 新建资源的DTO
     * @return 新建资源
     */
    @Timed
    @ApiOperation(value = "新建操作")
    @PostMapping
    public ResultDTO<WebLesseeDTO> create(@RequestBody @Valid final WebLesseeDTO lesseeDTO) {
        Lessee lessee = this.lesseeConverter.toModel(lesseeDTO);
        lessee = createOrUpdate(lesseeDTO, lessee);
        if (log.isInfoEnabled()) {
            log.info("{} instance {} was created.", Lessee.class.getSimpleName(), lessee.getId());
        }
        return this.lesseeConverter.toResultDTO(lessee);
    }

    /*
     * 创建或更新
     */
    private Lessee createOrUpdate(@Valid @RequestBody WebLesseeDTO lesseeDTO, Lessee lessee) {
        if(CollectionUtils.isNotEmpty(lesseeDTO.getLesseeContacts()) || CollectionUtils.isNotEmpty(lesseeDTO.getLesseeInvoices())) {
            List<LesseeContact> lesseeContacts = this.lesseeContactConverter.toListModel(lesseeDTO.getLesseeContacts());
            List<LesseeInvoice> lesseeInvoices = this.lesseeInvoiceConverter.toListModel(lesseeDTO.getLesseeInvoices());
            lessee = this.lesseeService.save(lessee, lesseeContacts, lesseeInvoices);
        } else {
            lessee = this.lesseeService.save(lessee);
        }
        return lessee;
    }

    /**
     * 删除操作
     *
     * @param id 实体对象ID
     * @return 操作结果
     */
    @Timed
    @ApiOperation(value = "删除操作")
    @DeleteMapping(value = "/{id}")
    public ResultDTO<Void> delete(@PathVariable final UUID id) {
        this.lesseeService.disable(id);
        if (log.isInfoEnabled()) {
            log.info("{} instance {} was disable.", Lessee.class.getSimpleName(), id);
        }
        return ResultDTO.success();
    }

    /**
     * 更新操作
     *
     * @param id 实体对象ID
     * @param lesseeDTO 更新资源的DTO
     * @return 更新后资源
     */
    @Timed
    @ApiOperation(value = "更新操作")
    @PutMapping(value = "/{id}")
    public ResultDTO<WebLesseeDTO> update(@PathVariable final UUID id, @RequestBody @Valid final WebLesseeDTO lesseeDTO) {
        lesseeDTO.setId(id);
        Lessee lessee = this.lesseeConverter.toModel(lesseeDTO);
        lessee = createOrUpdate(lesseeDTO, lessee);
        if (log.isInfoEnabled()) {
            log.info("{} instance {} was updated.", Lessee.class.getSimpleName(), lessee.getId());
        }
        return this.lesseeConverter.toResultDTO(lessee);
    }

    /**
     * 获取分页数据
     *
     * @param pageable 分页+排序参数
     * @return 分页数据
     */
    @Timed
    @ApiOperation(value = "获取列表分页数据")
    @PostMapping(value = "/s")
    public PageResultDTO<WebLesseeDTO> search(@QuerydslPredicate(root = Lessee.class) Predicate predicate,
                                              @PageableDefault(sort = {IConstants.CONST_PAGEABLE_CREATED_DATE},
                                                      direction = Sort.Direction.DESC) final Pageable pageable) {
        final Page<Lessee> models = this.lesseeRepository.findAll(predicate, pageable);
        return this.lesseeConverter.toResultDTO(models);
    }

    /**
     * 取得详细数据
     *
     * @param id 实体对象ID
     * @return 资源详细
     */
    @Timed
    @ApiOperation(value = "获取详细数据")
    @GetMapping(value = "/{id}")
    public ResultDTO<WebLesseeDTO> get(@PathVariable final UUID id) {
        final Lessee model = this.lesseeRepository.findById(id)
                    .orElseThrow(() -> ExceptionHolder.serviceException(TenantErrorCode.E1201000001, id.toString()));
        return this.lesseeConverter.toResultDTOForView(model);
    }
}
